package org.Yiran.timetale_re.item.rune.type.amplification.base;

import net.minecraft.client.Minecraft;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.Yiran.timetale_re.item.rune.base.AbstractRune;
import org.Yiran.timetale_re.item.rune.base.RuneItem;

/**
 * 增益类符文基类
 * <p>
 * 该类是所有增益类符文的抽象基类，定义了增益类符文的通用行为和属性。
 * 增益类符文通常提供临时的正面效果，如治疗、护盾、属性增强等。
 * 该类继承自AbstractRune，实现了符文的基本接口规范。
 * </p>
 */
public abstract class AmplificationRune extends AbstractRune {

    // ==============================
    // 构造方法
    // ==============================

    /**
     * 构造函数（使用默认冷却时间）
     * <p>
     * 创建一个新的增益类符文实例，使用默认的冷却时间。
     * </p>
     *
     * @param type 符文类型字符串标识，用于区分不同类型的增益符文
     */
    protected AmplificationRune(String type) {
        super(type, RuneItem.AMPLIFICATION);
    }

    /**
     * 构造函数（可自定义冷却时间）
     * <p>
     * 创建一个新的增益类符文实例，可以指定自定义的冷却时间。
     * </p>
     *
     * @param type     符文类型字符串标识，用于区分不同类型的增益符文
     * @param cooldown 符文使用后的冷却时间（单位：游戏刻，20 tick = 1秒）
     */
    protected AmplificationRune(String type, int cooldown) {
        super(type, RuneItem.AMPLIFICATION, cooldown);
    }

    // ==============================
    // 符文核心方法实现
    // ==============================

    /**
     * 使用符文时的处理逻辑
     * <p>
     * 当玩家使用增益类符文时调用此方法。该方法首先应用具体的增益效果，
     * 然后触发统一的视觉和音效反馈。
     * </p>
     *
     * @param stack  符文物品堆，包含具体符文信息的物品实例
     * @param level  当前世界对象，提供游戏环境上下文
     * @param player 使用符文的玩家对象
     */
    @Override
    public void onUse(ItemStack stack, Level level, Player player) {
        // 执行具体的增益效果，由子类实现
        applyAmplificationEffect(stack, level, player);

        // 触发统一的增幅符文视觉效果（音效和粒子效果）
        triggerAmplificationEffects(level, player);
    }

    // ==============================
    // 抽象方法定义
    // ==============================

    /**
     * 应用增益效果（由子类实现具体的增益逻辑）
     * <p>
     * 这是一个抽象方法，每个具体的增益符文子类都需要实现此方法来定义自己的增益效果。
     * 例如：生命恢复、护盾生成、属性增强等。
     * </p>
     *
     * @param stack  符文物品堆，包含具体符文信息的物品实例
     * @param level  当前世界对象，提供游戏环境上下文
     * @param player 使用符文的玩家对象
     */
    public abstract void applyAmplificationEffect(ItemStack stack, Level level, Player player);

    // ==============================
    // 持续效果处理
    // ==============================

    /**
     * 增益类符文默认不处理持续效果
     * <p>
     * 重写父类方法，默认情况下增益类符文不处理持续性效果。
     * 如果子类需要实现持续性效果，可以重写此方法。
     * </p>
     *
     * @param stack  符文物品堆，包含具体符文信息的物品实例
     * @param level  当前世界对象，提供游戏环境上下文
     * @param player 持有符文的玩家对象
     */
    @Override
    public void onTick(ItemStack stack, Level level, Player player) {
        // 增益类符文默认不处理持续效果
    }

    // ==============================
    // 视觉和音效反馈方法
    // ==============================

    /**
     * 触发统一的增幅符文视觉和音效
     * <p>
     * 播放统一的音效并调用客户端粒子效果生成方法，为玩家提供使用符文的即时反馈。
     * 使用类似不死图腾的音效以提供熟悉的用户体验。
     * </p>
     *
     * @param level  当前世界对象，提供游戏环境上下文
     * @param player 使用符文的玩家对象
     */
    protected void triggerAmplificationEffects(Level level, Player player) {
        // 播放类似不死图腾的音效，给玩家使用反馈
        level.playSound(null, player.blockPosition(), SoundEvents.TOTEM_USE,
                SoundSource.PLAYERS, 1.0F, 1.0F);

        // 在客户端生成粒子效果
        if (level.isClientSide()) {
            spawnTotemParticles(player);
        }
    }

    /**
     * 生成类似不死图腾的粒子效果
     * <p>
     * 在客户端生成视觉效果，显示符文激活时的粒子动画。
     * 仅在客户端执行，通过Minecraft实例检查当前玩家是否为本地玩家来确保正确的显示。
     * </p>
     *
     * @param player 使用符文的玩家对象
     */
    @OnlyIn(Dist.CLIENT)
    protected void spawnTotemParticles(Player player) {
        // 获取客户端Minecraft实例
        Minecraft mc = Minecraft.getInstance();
        // 检查当前玩家是否为本地玩家（即当前客户端控制的玩家）
        if (mc.player != null && mc.player.getUUID().equals(player.getUUID())) {
            // 触发屏幕上的不死图腾动画效果，显示正确的符文类型
            ItemStack runeStack = new ItemStack(RuneItem.getRuneItem());
            RuneItem.setRuneType(runeStack, this.getType());
            mc.gameRenderer.displayItemActivation(runeStack);
        }
    }
}